package com.ssy.lingxi.order.model.vo.mobile.response;

import com.ssy.lingxi.common.constant.order.OrderModeEnum;
import com.ssy.lingxi.common.constant.order.OrderSourceKindEnum;
import com.ssy.lingxi.order.model.constant.BuyerInnerStatusEnum;
import com.ssy.lingxi.order.model.constant.OrderOuterStatusEnum;
import com.ssy.lingxi.order.model.constant.OrderPromotionStatusEnum;
import com.ssy.lingxi.order.model.constant.OrderServiceContants;
import com.ssy.lingxi.order.utils.NumberUtil;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * App - 订单详情
 * @author 万宁
 * @version 2.0.0
 * @date 2021-09-25
 */
public class MobileOrderDetailVO implements Serializable {
    private static final long serialVersionUID = 1749790255995595011L;

    public MobileOrderDetailVO(Long orderId, String orderNo, Long shopId, String shopName, Long storeId, LocalDateTime createTime, Integer orderMode, Integer orderKind, Integer promotionStatus, Long groupId, Boolean hasRefund, Boolean canRefund, String digest, Long vendorMemberId, Long vendorRoleId, String vendorMemberName, String vendorLogo, String quoteNo, BigDecimal productAmount, BigDecimal freight, BigDecimal promotionAmount, BigDecimal couponAmount, BigDecimal deductionAmount, BigDecimal taxes, BigDecimal totalAmount, LocalDateTime archiveTime, Integer innerStatus, Integer outerStatus, Long consigneeId, String consignee, String deliverDate, String provinceName, String cityName, String districtName, String address, String phone, String contractFileName, String contractUrl,  MobileOrderInvoiceDetailVO invoice, MobileOrderRequirementDetailVO requirement) {
        this.orderId = orderId;
        this.orderNo = orderNo;
        this.shopId = shopId;
        this.shopName = shopName;
        this.storeId = storeId;
        this.createTime = createTime == null ? "" : createTime.format(OrderServiceContants.DEFAULT_TIME_FORMATTER);
        this.orderMode = orderMode;
        this.orderModeName = OrderModeEnum.getNameByCode(orderMode);
        this.groupOrder = orderKind.equals(OrderSourceKindEnum.GROUP.getCode());
        this.promotionStatus = NumberUtil.isNullOrZero(promotionStatus) ? 0 : promotionStatus;
        this.promotionStatusName = OrderPromotionStatusEnum.getNameByCode(NumberUtil.isNullOrZero(promotionStatus) ? 0 : promotionStatus);
        this.groupId = NumberUtil.isNullOrZero(groupId) ? 0L : groupId;
        this.showInvite = orderKind.equals(OrderSourceKindEnum.GROUP.getCode()) && outerStatus.equals(OrderOuterStatusEnum.TO_CONFIRM_DELIVERY.getCode()) && this.promotionStatus.equals(OrderPromotionStatusEnum.GROUP_WAITING_CONFIRM.getCode());
        this.showRefund = orderKind.equals(OrderSourceKindEnum.GROUP.getCode()) && outerStatus.equals(OrderOuterStatusEnum.CANCELLED.getCode()) && Objects.nonNull(hasRefund) && !hasRefund && Objects.nonNull(canRefund) && canRefund;
        this.digest = digest;
        this.vendorMemberId = vendorMemberId;
        this.vendorRoleId = vendorRoleId;
        this.vendorMemberName = vendorMemberName;
        this.logo = StringUtils.hasLength(vendorLogo) ? vendorLogo : "";
        this.quoteNo = quoteNo;
        this.productAmount = NumberUtil.formatAmount(productAmount);
        this.freight = NumberUtil.formatAmount(freight);
        this.promotionAmount = NumberUtil.formatAmount(promotionAmount);
        this.couponAmount = NumberUtil.formatAmount(couponAmount);
        this.deductionAmount = NumberUtil.formatAmount(deductionAmount);
        this.taxes = NumberUtil.formatAmount(taxes);
        this.totalAmount = NumberUtil.formatAmount(totalAmount);
        this.archiveTime = archiveTime == null ? "" : archiveTime.format(OrderServiceContants.DEFAULT_TIME_FORMATTER);
        this.innerStatus = innerStatus;
        this.innerStatusName = BuyerInnerStatusEnum.getNameByCode(innerStatus);
        this.outerStatus = outerStatus;
        this.outerStatusName = OrderOuterStatusEnum.getNameByCode(outerStatus);
        this.consigneeId = NumberUtil.isNullOrZero(consigneeId) ? 0L : consigneeId;
        this.consignee = StringUtils.hasLength(consignee) ? consignee : "";
        this.deliverDate = StringUtils.hasLength(deliverDate) ? deliverDate : "";
        this.areaName = (StringUtils.hasLength(provinceName) ? provinceName : "").concat(StringUtils.hasLength(cityName) ? cityName : "").concat(StringUtils.hasLength(districtName) ? districtName : "");
        this.address = StringUtils.hasLength(address) ? address : "";
        this.phone = StringUtils.hasLength(phone) ? phone : "";
        this.contractFileName = StringUtils.hasLength(contractFileName) ? contractFileName : "";
        this.contractUrl = StringUtils.hasLength(contractUrl) ? contractUrl : "";
        this.invoiceTitle = invoice == null ? "" : invoice.getTitle();
        this.invoice = invoice;
        this.requirement = requirement;
        this.products = new ArrayList<>();
        this.payments = new ArrayList<>();
        this.deliveries = new ArrayList<>();
    }

    /**
     * 订单Id
     */
    private Long orderId;

    /**
     * 订单编号
     */
    private String orderNo;

    /**
     * 订单来源商城Id
     */
    private Long shopId;

    /**
     * 订单来源商城名称
     */
    private String shopName;

    /**
     * 门店Id
     */
    private Long storeId;

    /**
     * 下单时间，格式为yyyy-MM-dd HH:mm:ss
     */
    private String createTime;

    /**
     * 下单模式
     */
    private Integer orderMode;

    /**
     * 下单模式名称
     */
    private String orderModeName;

    /**
     * 订单摘要
     */
    private String digest;

    /**
     * 供应商会员Id
     */
    private Long vendorMemberId;

    /**
     * 供应商会员角色Id
     */
    private Long vendorRoleId;

    /**
     * 供应商会员名称
     */
    private String vendorMemberName;

    /**
     * 供应商会员店铺Logo
     */
    private String logo;

    /**
     * 对应报价单号
     */
    private String quoteNo;

    /**
     * 商品金额
     */
    private String productAmount;

    /**
     * 运费
     */
    private String freight;

    /**
     * 促销活动金额
     */
    private String promotionAmount;

    /**
     * 优惠券金额
     */
    private String couponAmount;

    /**
     * 积分抵扣总金额
     */
    private String deductionAmount;

    /**
     * 税费（根据跨境电商进口商品税率计算）
     */
    private String taxes;

    /**
     * 订单总金额 = 订单商品总金额 + 运费 - 促销活动金额 - 优惠券金额
     */
    private String totalAmount;

    /**
     * 归档时间，格式为yyyy-MM-dd HH:mm:ss，如未归档则此字段为空字符串
     */
    private String archiveTime;

    /**
     * 订单内部状态 2-待审核（一级），4-待审核（二级）
     */
    private Integer innerStatus;

    /**
     * 订单内部状态名称
     */
    private String innerStatusName;

    /**
     * 订单外部状态
     */
    private Integer outerStatus;

    /**
     * 订单外部状态名称
     */
    private String outerStatusName;

    /**
     * 是否是“拼团”订单
     */
    private Boolean groupOrder;

    /**
     * 拼团Id，如果不是“拼团订单”，此字段值为0
     */
    private Long groupId;

    /**
     * 是否显示“邀请好友拼团”按钮
     */
    private Boolean showInvite;

    /**
     * 是否显示“退款”按钮
     */
    private Boolean showRefund;

    /**
     * 营销活动（拼团）状态枚举，0-无营销活动，1-拼团中，2-等待拼团确认，3-拼团失败，4-拼团成功
     */
    private Integer promotionStatus;

    /**
     * 营销活动（拼团）状态名称
     */
    private String promotionStatusName;

    /**
     * 收货人地址Id
     */
    private Long consigneeId;

    /**
     * 收货人姓名
     */
    private String consignee;

    /**
     * 交付日期，格式为yyyy-MM-dd
     */
    private String deliverDate;

    /**
     * 收货人所在的省市区（名称拼接）
     */
    private String areaName;

    /**
     * 收货人详细地址
     */
    private String address;

    /**
     * 收货人手机号码
     */
    private String phone;

    /**
     * 合同文件名称，如没有合同此字段为空字符串
     */
    private String contractFileName;

    /**
     * 合同文件Url, 如没有合同此字段为空字符串
     */
    private String contractUrl;

    /**
     * 支付次数，如无支付则为0
     */
    private Integer payTimes;

    /**
     * 标签，表示“第n次”次支付
     */
    private Integer payTag;

    /**
     * 支付时间，格式为yyyy-MM-dd，如无支付，或大于1次支付则为空字符串
     */
    private String payTime;

    /**
     * 支付渠道名称，如无支付，或大于1次支付则为空字符串
     */
    private String payChannelName;

    /**
     * 发货时间，格式为yyyy-MM-dd HH:mm:ss，如还没发货则为空字符串
     */
    private String deliverTime;

    /**
     * 收货时间，格式为yyyy-MM-dd HH:mm:ss，如还没收货则为空字符串
     */
    private String receiptTime;

    /**
     * 发票台头，如没有发票则此字段为空字符串
     */
    private String invoiceTitle;

    /**
     * 发票详情，如没有发票则此字段为空
     */
    private MobileOrderInvoiceDetailVO invoice;

    /**
     * 订单其他要求
     */
    private MobileOrderRequirementDetailVO requirement;

    /**
     * 订单商品列表
     */
    private List<MobileOrderProductDetailVO> products;

    /**
     * 支付记录列表
     */
    private List<MobileOrderPaymentDetailVO> payments;

    /**
     * 收发货记录（物流信息）
     */
    private List<MobileOrderDeliveryDetailVO> deliveries;

    public Long getOrderId() {
        return orderId;
    }

    public void setOrderId(Long orderId) {
        this.orderId = orderId;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public Long getShopId() { return shopId; }

    public void setShopId(Long shopId) { this.shopId = shopId; }

    public String getShopName() { return shopName; }

    public void setShopName(String shopName) { this.shopName = shopName; }

    public Long getStoreId() {
        return storeId;
    }

    public void setStoreId(Long storeId) {
        this.storeId = storeId;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public Integer getOrderMode() {
        return orderMode;
    }

    public void setOrderMode(Integer orderMode) {
        this.orderMode = orderMode;
    }

    public String getOrderModeName() {
        return orderModeName;
    }

    public void setOrderModeName(String orderModeName) {
        this.orderModeName = orderModeName;
    }

    public String getDigest() {
        return digest;
    }

    public void setDigest(String digest) {
        this.digest = digest;
    }

    public Long getVendorMemberId() {
        return vendorMemberId;
    }

    public void setVendorMemberId(Long vendorMemberId) {
        this.vendorMemberId = vendorMemberId;
    }

    public Long getVendorRoleId() {
        return vendorRoleId;
    }

    public void setVendorRoleId(Long vendorRoleId) {
        this.vendorRoleId = vendorRoleId;
    }

    public String getVendorMemberName() {
        return vendorMemberName;
    }

    public void setVendorMemberName(String vendorMemberName) {
        this.vendorMemberName = vendorMemberName;
    }

    public String getLogo() { return logo; }

    public void setLogo(String logo) { this.logo = logo; }

    public String getQuoteNo() {
        return quoteNo;
    }

    public void setQuoteNo(String quoteNo) {
        this.quoteNo = quoteNo;
    }

    public String getProductAmount() {
        return productAmount;
    }

    public void setProductAmount(String productAmount) {
        this.productAmount = productAmount;
    }

    public String getFreight() {
        return freight;
    }

    public void setFreight(String freight) {
        this.freight = freight;
    }

    public String getPromotionAmount() {
        return promotionAmount;
    }

    public void setPromotionAmount(String promotionAmount) {
        this.promotionAmount = promotionAmount;
    }

    public String getCouponAmount() {
        return couponAmount;
    }

    public void setCouponAmount(String couponAmount) {
        this.couponAmount = couponAmount;
    }

    public String getDeductionAmount() {
        return deductionAmount;
    }

    public void setDeductionAmount(String deductionAmount) {
        this.deductionAmount = deductionAmount;
    }

    public String getTaxes() {
        return taxes;
    }

    public void setTaxes(String taxes) {
        this.taxes = taxes;
    }

    public String getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(String totalAmount) {
        this.totalAmount = totalAmount;
    }

    public String getArchiveTime() {
        return archiveTime;
    }

    public void setArchiveTime(String archiveTime) {
        this.archiveTime = archiveTime;
    }

    public Integer getInnerStatus() { return innerStatus; }

    public void setInnerStatus(Integer innerStatus) { this.innerStatus = innerStatus; }

    public String getInnerStatusName() { return innerStatusName; }

    public void setInnerStatusName(String innerStatusName) { this.innerStatusName = innerStatusName; }

    public Integer getOuterStatus() { return outerStatus; }

    public void setOuterStatus(Integer outerStatus) { this.outerStatus = outerStatus; }

    public String getOuterStatusName() { return outerStatusName; }

    public void setOuterStatusName(String outerStatusName) { this.outerStatusName = outerStatusName; }

    public Boolean getGroupOrder() { return groupOrder; }

    public void setGroupOrder(Boolean groupOrder) { this.groupOrder = groupOrder; }

    public Long getGroupId() { return groupId; }

    public void setGroupId(Long groupId) { this.groupId = groupId; }

    public Boolean getShowInvite() { return showInvite; }

    public void setShowInvite(Boolean showInvite) { this.showInvite = showInvite; }

    public Boolean getShowRefund() {
        return showRefund;
    }

    public void setShowRefund(Boolean showRefund) {
        this.showRefund = showRefund;
    }

    public Integer getPromotionStatus() { return promotionStatus; }

    public void setPromotionStatus(Integer promotionStatus) { this.promotionStatus = promotionStatus; }

    public String getPromotionStatusName() { return promotionStatusName; }

    public void setPromotionStatusName(String promotionStatusName) { this.promotionStatusName = promotionStatusName; }

    public Long getConsigneeId() {
        return consigneeId;
    }

    public void setConsigneeId(Long consigneeId) {
        this.consigneeId = consigneeId;
    }

    public String getConsignee() {
        return consignee;
    }

    public void setConsignee(String consignee) {
        this.consignee = consignee;
    }

    public String getDeliverDate() {
        return deliverDate;
    }

    public void setDeliverDate(String deliverDate) {
        this.deliverDate = deliverDate;
    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getContractFileName() {
        return contractFileName;
    }

    public void setContractFileName(String contractFileName) {
        this.contractFileName = contractFileName;
    }

    public String getContractUrl() {
        return contractUrl;
    }

    public void setContractUrl(String contractUrl) {
        this.contractUrl = contractUrl;
    }

    public Integer getPayTag() { return payTag; }

    public void setPayTag(Integer payTag) { this.payTag = payTag; }

    public Integer getPayTimes() {
        return payTimes;
    }

    public void setPayTimes(Integer payTimes) {
        this.payTimes = payTimes;
    }

    public String getPayTime() {
        return payTime;
    }

    public void setPayTime(String payTime) {
        this.payTime = payTime;
    }

    public String getPayChannelName() {
        return payChannelName;
    }

    public void setPayChannelName(String payChannelName) {
        this.payChannelName = payChannelName;
    }

    public String getDeliverTime() {
        return deliverTime;
    }

    public void setDeliverTime(String deliverTime) {
        this.deliverTime = deliverTime;
    }

    public String getReceiptTime() {
        return receiptTime;
    }

    public void setReceiptTime(String receiptTime) {
        this.receiptTime = receiptTime;
    }

    public String getInvoiceTitle() {
        return invoiceTitle;
    }

    public void setInvoiceTitle(String invoiceTitle) {
        this.invoiceTitle = invoiceTitle;
    }

    public MobileOrderInvoiceDetailVO getInvoice() {
        return invoice;
    }

    public void setInvoice(MobileOrderInvoiceDetailVO invoice) {
        this.invoice = invoice;
    }

    public MobileOrderRequirementDetailVO getRequirement() {
        return requirement;
    }

    public void setRequirement(MobileOrderRequirementDetailVO requirement) {
        this.requirement = requirement;
    }

    public List<MobileOrderProductDetailVO> getProducts() {
        return products;
    }

    public void setProducts(List<MobileOrderProductDetailVO> products) {
        this.products = products;
    }

    public List<MobileOrderPaymentDetailVO> getPayments() {
        return payments;
    }

    public void setPayments(List<MobileOrderPaymentDetailVO> payments) {
        this.payments = payments;
        this.payTimes = this.payments.size();
        this.payTime = this.payments.size() == 1 ? this.payments.get(0).getPayTime() : "";
        this.payChannelName = this.payments.size() == 1 ? this.payments.get(0).getPayChannelName() : "";
        this.payTag = payments.stream().filter(MobileOrderPaymentDetailVO::getShowPay).map(MobileOrderPaymentDetailVO::getTag).findFirst().orElse(0);
    }

    public List<MobileOrderDeliveryDetailVO> getDeliveries() {
        return deliveries;
    }

    public void setDeliveries(List<MobileOrderDeliveryDetailVO> deliveries) {
        this.deliveries = deliveries;
        this.deliverTime = this.deliveries.stream().filter(delivery -> StringUtils.hasLength(delivery.getDeliverTime())).min(Comparator.comparingInt(MobileOrderDeliveryDetailVO::getBatchNo)).map(MobileOrderDeliveryDetailVO::getDeliverTime).orElse("");
        this.receiptTime = this.deliveries.stream().filter(delivery -> StringUtils.hasLength(delivery.getReceiptTime())).max(Comparator.comparingInt(MobileOrderDeliveryDetailVO::getBatchNo)).map(MobileOrderDeliveryDetailVO::getReceiptTime).orElse("");
    }
}
